/*
 * Define method
 * lfs_core.h
 *
 *  Created on: Dec 8, 2012
 *      Author: duoln
 */

#ifndef LFS_CORE_H_
#define LFS_CORE_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdlib.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>

/**  common header files   **/
#include "lfs_flag.h"
#include "lfs_error.h"

/* Method */
#include "list.h"

typedef struct _lfs_ LFS;

typedef struct _MetaHost_{
	char ip[FILENAME_LEN];
	int32_t port;
	int32_t status;//_chunkserver_status
	uint32_t count;
}MetaHost;

typedef struct _MetaChunk_{
	int64_t id;
	List* hosts;//List<MetaIP>
	int64_t start;
	int64_t end;
}MetaChunk;

typedef struct _meta_file_{
    char namespace[FILENAME_LEN];
    int32_t min_replica;
    int32_t max_replica;
    List* mchunks;//List<MetaChunk>
    int64_t length;
    int64_t create_time;
    int64_t last_modify_time;
    uint8_t status;
}MetaFile;

typedef struct _file_stream_ FileStream;

/**
 * Init file system, init config
 *
 * @param master_addr [The path of master lfs.conf]
 * @return Instence of lfs
 */
LFS* lfs_init(const char* master_addr, int port);

/**
 * Destory the instance, free memory
 * @param lfs [Instance of lfs]
 * @return
 */
void lfs_destory(LFS* lfs);

/**
 * Create a new file.
 * the writing op means succ only the replica num >= min_replica
 * @param lfs [Instance of lfs]
 * @param name_space [Need to create a file name space]
 * @param min_replica [Able to successfully operate min replica]
 * @param max_replica [Max replica of file in system]
 *
 * @return Code of lfs. if success return LFS_SUCC
 */
Status lfs_fcreate(LFS* lfs, const char* name_space, int32_t min_replica, int32_t max_replica);

/**
 * Open a new file stream
 */
FileStream* lfs_fopen(LFS* lfs, const char* name_space);

/**
 * Delete the file
 */
Status lfs_fremove(LFS* lfs, const char* name_space);

/**
 * Append data to file
 */
Status lfs_fwrite(FileStream* file, void* data, int64_t size, int64_t stamp);

/**
 * Read data range by start and end time
 * [start, end]
 */
Status lfs_fread(FileStream* file, int64_t start, int64_t end, /*out*/List* sfiles);

/**
 * Delete data range by start and end time
 */
Status lfs_fdelete(FileStream* file, int64_t start, int64_t end);

/**
 * Close the FileStream
 */
Status lfs_fclose(FileStream* file);

/* other method */

Status lfs_get_metafile(LFS* lfs, const char* name_space);

Status lfs_modify_replica(LFS* lfs, const char* name_space, int32_t min_replica, int32_t max_replica);

Status lfs_rename_file(LFS* lfs, const char* name_space, const char* new_name_space);

Status lfs_list_file_by_prefix(LFS* lfs, const char* prefix, /*out*/List* file_names);

/* */
MetaFile* meta_file_init(const char* namespace, int32_t min_replica, int32_t max_replica);

#ifdef __cplusplus
}
#endif

#endif /* LFS_CORE_H_ */
